using Gtk;
using System;
using System.Data;

namespace Serpis
{
	/// <summary>
	/// Rellena el treeView ejecutando el commandText sobre la dbConnection indicados en el constructor.
	/// </summary>
	internal class TreeViewHelper
	{
		private TreeView treeView;
		private ListStore listStore;
		private IDbCommand dbCommand;
		
		public TreeViewHelper (TreeView treeView, IDbConnection dbConnection, string commandText)
		{
			this.treeView = treeView;
			
			dbCommand = dbConnection.CreateCommand();
			dbCommand.CommandText = commandText;
			IDataReader dataReader = dbCommand.ExecuteReader();
			
			Type[] types = new Type[dataReader.FieldCount];
			for (int index = 0; index < dataReader.FieldCount; index++) {
				treeView.AppendColumn(dataReader.GetName(index), new CellRendererText(), "text", index);
				types[index] = typeof(string);
			}
			
			listStore = new ListStore(types);
			
			refresh(dataReader);
						
			treeView.Model = listStore;
			
			treeView.Selection.Changed += delegate {
				raiseChanged();
			};
		}
		
		public void Refresh()
		{
			IDataReader dataReader = dbCommand.ExecuteReader();
			//**	Con el siguiente if, conseguiremos crear las columnas necesarias para el treeView en función de la consulta realizada
			if(treeView.Columns.Length==0)
			{
				for(int i=0;i<dataReader.FieldCount;i++)
				{
					treeView.AppendColumn(dataReader.GetName(i), new CellRendererText(), "text", i);
				}
			}
			listStore.Clear();
			refresh(dataReader);
		}
		
		public void Refresh(string commandText)
		{
			//Console.WriteLine(commandText);
			//**	Evitamos que la consulta sea null o vacia definiendo una consulta por defecto...
			if(commandText == null || commandText == "")
				commandText = "SELECT * FROM articulo;";
			dbCommand.CommandText = commandText;
			foreach(TreeViewColumn column in treeView.Columns)
			{
				treeView.RemoveColumn(column);
			}
			Refresh();
		}
		
		private void refresh(IDataReader dataReader)
		{
			while (dataReader.Read()) {
				object[] values = new object[dataReader.FieldCount];
				dataReader.GetValues(values);
				for (int i = 0; i < values.Length; i++)
					values[i] = values[i].ToString();
				
				listStore.AppendValues(values);
			}
			
			dataReader.Close();			
		}
		
		public bool HasSelected {
			get { return treeView.Selection.CountSelectedRows() > 0;} 
		}
		
		/// <summary>
		/// Devuelve el valor de la columna indicada de la fila seleccionada.
		/// Precondición: El método supone, y no lo comprueba, que hay una fila seleccionada.
		/// </summary>
		public object GetValue(int columnIndex)
		{
			TreeIter treeIter;
			treeView.Selection.GetSelected(out treeIter);
						
			return listStore.GetValue(treeIter, columnIndex);
		}
		
		private void raiseChanged()
		{
			if (Changed != null)
				Changed(this, EventArgs.Empty);
		}

		public event EventHandler Changed;
	}
}
